package br.unirio.octopus.servicos.implementacao;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.unirio.octopus.dados.RepositorioDeJogo;
import br.unirio.octopus.dados.RepositorioDePalpite;
import br.unirio.octopus.dominio.Jogo;
import br.unirio.octopus.dominio.Palpite;
import br.unirio.octopus.dominio.PalpiteVO;
import br.unirio.octopus.dominio.Usuario;
import br.unirio.octopus.excecao.ExcecaoDaAplicacao;
import br.unirio.octopus.servicos.IServicoDePalpite;
import br.unirio.octopus.util.UtilitarioDeDatas;

@Service
public class ServicoDePalpite implements IServicoDePalpite{

	@Autowired
	private RepositorioDeJogo repositorioDeJogos;
	@Autowired
	private RepositorioDePalpite repositorioDePalpites;
		
	@Transactional
	public void criarPalpite(Palpite palpite) throws ExcecaoDaAplicacao{
		if(palpiteValido(palpite)){
			repositorioDePalpites.salvar(palpite);			
		}
		else throw new ExcecaoDaAplicacao("erro.palpite.horario");
	}

	private boolean palpiteValido(Palpite palpite) {
		Date dataDoJogo = palpite.getJogo().getDiaEHorario();
		return UtilitarioDeDatas.getInstancia().palpiteDeJogoPodeSerEditadoNestaData(new Date(),dataDoJogo);
	}
	
	public List<PalpiteVO> obterJogosEPalpitesDoUsuario(Usuario usuario){
		
		List<Jogo> todosJogos = repositorioDeJogos.obterTodosJogosAteFaseAtual();
		List<Palpite> palpitesDoUsuario = repositorioDePalpites.obterPalpitesDeUsuario(usuario);
		List<PalpiteVO> retorno = new ArrayList<PalpiteVO>();
		
		for (Jogo jogo : todosJogos) {
			Palpite palpite = obterPalpiteDeJogo(jogo, palpitesDoUsuario);
			PalpiteVO vo = new PalpiteVO(jogo,palpite);
			vo.setJogoEditavel(UtilitarioDeDatas.getInstancia().palpiteDeJogoPodeSerEditadoNestaData(new Date(), vo.getDataDoJogo()));
			retorno.add(vo);
		}
		
		Collections.sort(retorno);
		return retorno;
	}
	
	public Palpite obterPalpiteDeJogo(Jogo jogo, List<Palpite> palpites){
		for (Palpite palpite : palpites) {
			if(palpite.getJogo().equals(jogo)){
				return palpite;
			}				
		}
		return null;
	}
	
//	public List<PalpiteVO> obterJogosEPalpitesDoUsuario(Usuario usuario){
//		
//		List<PalpiteVO> listaVO = repositorioDePalpites.obterJogosEPalpitesDeUsuario(usuario);
//		List<PalpiteVO> retorno = new ArrayList<PalpiteVO>();
//		for (PalpiteVO palpiteVO : listaVO) {
//			if(palpiteVO.getIdDoUsuario()!=null){
//				if(palpiteVO.getIdDoUsuario().equals(usuario.getIdDoUsuario())){
//					palpiteVO.setJogoEditavel(UtilitarioDeDatas.getInstancia().palpiteDeJogoPodeSerEditadoNestaData(new Date(), palpiteVO.getDataDoJogo())); //new Date() faz um novo objeto date com a data atual
//					retorno.add(palpiteVO);					
//				}
//			}
//			else{
//				palpiteVO.setJogoEditavel(UtilitarioDeDatas.getInstancia().palpiteDeJogoPodeSerEditadoNestaData(new Date(), palpiteVO.getDataDoJogo())); //new Date() faz um novo objeto date com a data atual
//				retorno.add(palpiteVO);
//			}
//		}
//		
//		return retorno;
//	}

	@Override
	public Jogo obterJogoPorId(Integer idDoJogo) {
		return repositorioDeJogos.obterPorId(idDoJogo);
	}

	@Override
	public Palpite obterPalpitePorId(Integer idDoPalpite) {
		return repositorioDePalpites.obterPorId(idDoPalpite);
	}
	
	@Override
	public Palpite obterPalpiteDeUsuarioPorIdDeJogo(Usuario usuario, Integer idDoJogo) throws ExcecaoDaAplicacao {
		return repositorioDePalpites.obterPalpiteDeUsuarioPorIdDoJogo(usuario, idDoJogo);
	}

	@Transactional
	@Override
	public void atualizarPalpite(Palpite palpite){
		if(palpiteValido(palpite)){
			repositorioDePalpites.alterar(palpite);			
		}
		
	}
	
	public List<Palpite> obterPalpitesDeUsuario(Usuario usuario)
	{
		return repositorioDePalpites.obterPalpitesDeUsuario(usuario);
	}
	

}
